package com.fdb.smcts.excel;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

import com.alibaba.excel.metadata.BaseRowModel;

/**
 * 读取excel，fluent API
 * 
 * @param <T>
 *            模板类型
 * @author hengyh
 * @since 2019年3月15日 下午3:04:38
 * @version 1.0
 */
public class ExcelReadFactory<T extends BaseRowModel> {
    /** excel文件的位置，可以是classpath下的相对路径，也可以是文件系统的路径 */
    private String filePath;
    /** 文件的输入流 */
    private InputStream inputStream;
    /** 模板 */
    private T template;
    /** 可选，读入的sheet页 */
    private Integer sheetNo;
    /** 可选，表头行数 */
    private Integer headLine;

    public ExcelReadFactory(final Builder<T> builder) {
        this.filePath = builder.filePath;
        this.inputStream = builder.inputStream;
        this.template = builder.template;
        this.sheetNo = builder.sheetNo;
        this.headLine = builder.headLine;
    }

    public List<T> read() throws IOException {
        if (inputStream != null) {
            return ExcelUtil.readExcel(inputStream, template, sheetNo, headLine);
        } else if (filePath != null && sheetNo != null) {
            return ExcelUtil.readExcel(filePath, template, sheetNo, headLine);
        } else {
            return ExcelUtil.readExcel(filePath, template, headLine);
        }
    }

    public static <T extends BaseRowModel> Builder<T> create(T template) {
        return new Builder<T>().template(template);
    }

    public static class Builder<T extends BaseRowModel> {
        /** excel文件的位置，可以是classpath下的相对路径，也可以是文件系统的路径 */
        private String filePath;
        /** 文件的输入流 */
        private InputStream inputStream;
        /** 模板 */
        private T template;
       /** 可选，读入的sheet页 */
        private Integer sheetNo;
        /** 可选，表头行数 */
        private Integer headLine;

        public Builder<T> filePath(String filePath) {
            this.filePath = filePath;
            return this;
        }
        public Builder<T> template(T template) {
            this.template = template;
            return this;
        }
        public Builder<T> inputStream(InputStream inputStream) {
            this.inputStream = inputStream;
            return this;
        }
        public Builder<T> sheetNo(Integer sheetNo) {
            this.sheetNo = sheetNo;
            return this;
        }
        public Builder<T> headLine(Integer headLine) {
            this.headLine = headLine;
            return this;
        }
        public List<T> read() throws IOException {
            return build().read();
        } 

        public ExcelReadFactory<T> build() {
            return new ExcelReadFactory<T>(this);
        }
    }
}